`include "common.svh"
module issue_wakeup #(
    parameter ALU_NUM = 2,
    parameter BRU_NUM = 1,
    parameter LSU_NUM = 1,
    parameter MDU_NUM = 1,
    parameter WAKEUP_WIDTH = ALU_NUM + BRU_NUM + LSU_NUM + MDU_NUM
) (
    input i_alu_valid[ALU_NUM-1:0],
    input ISSUE_OP i_alu_iop[ALU_NUM-1:0],
    input i_alu_ready,
    input i_bru_valid[BRU_NUM-1:0],
    input ISSUE_OP i_bru_iop[BRU_NUM-1:0],
    input i_bru_ready,

    input         i_mdu_early_wakeup_valid  [MDU_NUM-1:0],
    input PRF_IDX i_mdu_early_wakeup_prf_idx[MDU_NUM-1:0],
    input         i_mem_early_wakeup_valid,
    input PRF_IDX i_mem_early_wakeup_prf_idx,

    output o_wakeup_valid[WAKEUP_WIDTH-1:0],
    output PRF_IDX o_wakeup_prf_idx[WAKEUP_WIDTH-1:0]
);
  logic i_alu_fire[ALU_NUM-1:0];
  logic i_bru_fire[BRU_NUM-1:0];
  genvar gi;
  generate
    for (gi = 0; gi < ALU_NUM; gi = gi + 1) begin : ALU_Wakeup
      assign i_alu_fire[gi] = i_alu_valid[gi] & i_alu_ready;
      assign o_wakeup_valid[gi] = i_alu_fire[gi] & i_alu_iop[gi].rop.fop.dop.has_rd;
      assign o_wakeup_prf_idx[gi] = i_alu_iop[gi].rop.pdst;
    end

    for (gi = 0; gi < BRU_NUM; gi = gi + 1) begin : BRU_Wakeup
      assign i_bru_fire[gi] = i_bru_valid[gi] & i_bru_ready;
      assign o_wakeup_valid[ALU_NUM+gi] = i_bru_fire[gi] & i_bru_iop[gi].rop.fop.dop.has_rd;
      assign o_wakeup_prf_idx[ALU_NUM+gi] = i_bru_iop[gi].rop.pdst;
    end

    assign o_wakeup_valid[ALU_NUM+BRU_NUM]   = i_mem_early_wakeup_valid;
    assign o_wakeup_prf_idx[ALU_NUM+BRU_NUM] = i_mem_early_wakeup_prf_idx;

    for (gi = 0; gi < MDU_NUM; gi = gi + 1) begin : MDU_Wakeup
      assign o_wakeup_valid[ALU_NUM+BRU_NUM+LSU_NUM+gi]   = i_mdu_early_wakeup_valid[gi];
      assign o_wakeup_prf_idx[ALU_NUM+BRU_NUM+LSU_NUM+gi] = i_mdu_early_wakeup_prf_idx[gi];
    end
  endgenerate
endmodule
